//////////////////////////////////////////////////////////////////////////
// Author:		Dan Polak
// Date:		3/9/2010
// Last Mod:	3/25/2011
//
// File:		Objects.h
//
// Purpose:		This file will define the structures to hold the information
//				for the objects to be used in the editor. For base implimentation
//				this will only define the AABB struct, but will eventually
//				hold structs for any objects that may be needed in projects.
//////////////////////////////////////////////////////////////////////////

#ifndef _OBJECTS_H
#define _OBJECTS_H

#include "Math.h"

enum OBJECTS{MOBJ_BASE, MOBJ_BOX, M0BJ_BASE_MOVER, MOBJ_BASE_TRIGGER, MOBJ_CYLINDER, OBJ_OUTTER_WALL, OBJ_ROOM_WALL, MOBJ_MAX};

struct OBJBase
{
	int m_nType;
};

struct AABB : public OBJBase
{
	vec3f	m_vMinPos;
	vec3f	m_vMaxPos;

	int m_nZone;		//Determines which Zone the object is in.
						//if the zone is -1 it will be computed no matter where it is

	bool m_bChecked;	//Collision variable

	void Create(vec3f vMin, vec3f vMax, int nZone, int nType)
	{
		this->m_nType = nType;
		this->m_nZone = nZone;
		this->m_vMinPos = vMin;
		this->m_vMaxPos = vMax;
		this->m_bChecked = false;
	}

	void OBJTranslate(vec3f vTrans)
	{
		this->m_vMinPos.x += vTrans.x;
		this->m_vMaxPos.x += vTrans.x;

		this->m_vMinPos.y += vTrans.y;
		this->m_vMaxPos.y += vTrans.y;

		this->m_vMinPos.z += vTrans.z;
		this->m_vMaxPos.z += vTrans.z;
	}

	void Render()
	{
		glBegin(GL_QUADS);
		{
			//sides
			glNormal3f(-1.0f, 0.0f, 0.0f);
			glVertex3f(this->m_vMinPos.x, this->m_vMinPos.y, this->m_vMinPos.z);
			glVertex3f(this->m_vMinPos.x, this->m_vMaxPos.y, this->m_vMinPos.z);
			glVertex3f(this->m_vMinPos.x, this->m_vMaxPos.y, this->m_vMaxPos.z);
			glVertex3f(this->m_vMinPos.x, this->m_vMinPos.y, this->m_vMaxPos.z);

			glNormal3f(0.0f, 0.0f, -1.0f);
			glVertex3f(this->m_vMinPos.x, this->m_vMinPos.y, this->m_vMinPos.z);
			glVertex3f(this->m_vMaxPos.x, this->m_vMinPos.y, this->m_vMinPos.z);
			glVertex3f(this->m_vMaxPos.x, this->m_vMaxPos.y, this->m_vMinPos.z);
			glVertex3f(this->m_vMinPos.x, this->m_vMaxPos.y, this->m_vMinPos.z);

			glNormal3f(1.0f, 0.0f, 0.0f);
			glVertex3f(this->m_vMaxPos.x, this->m_vMinPos.y, this->m_vMaxPos.z);
			glVertex3f(this->m_vMaxPos.x, this->m_vMaxPos.y, this->m_vMaxPos.z);
			glVertex3f(this->m_vMaxPos.x, this->m_vMaxPos.y, this->m_vMinPos.z);
			glVertex3f(this->m_vMaxPos.x, this->m_vMinPos.y, this->m_vMinPos.z);

			glNormal3f(0.0f, 0.0f, 1.0f);
			glVertex3f(this->m_vMaxPos.x, this->m_vMinPos.y, this->m_vMaxPos.z);
			glVertex3f(this->m_vMinPos.x, this->m_vMinPos.y, this->m_vMaxPos.z);
			glVertex3f(this->m_vMinPos.x, this->m_vMaxPos.y, this->m_vMaxPos.z);
			glVertex3f(this->m_vMaxPos.x, this->m_vMaxPos.y, this->m_vMaxPos.z);

			//Bottom
			glNormal3f(0.0f, -1.0f, 0.0f);
			glVertex3f(this->m_vMinPos.x, this->m_vMinPos.y, this->m_vMinPos.z);
			glVertex3f(this->m_vMinPos.x, this->m_vMinPos.y, this->m_vMaxPos.z);
			glVertex3f(this->m_vMaxPos.x, this->m_vMinPos.y, this->m_vMaxPos.z);
			glVertex3f(this->m_vMaxPos.x, this->m_vMinPos.y, this->m_vMinPos.z);

			//Top
			glNormal3f(0.0f, 1.0f, 0.0f);
			glVertex3f(this->m_vMinPos.x, this->m_vMaxPos.y, this->m_vMinPos.z);
			glVertex3f(this->m_vMaxPos.x, this->m_vMaxPos.y, this->m_vMinPos.z);
			glVertex3f(this->m_vMaxPos.x, this->m_vMaxPos.y, this->m_vMaxPos.z);
			glVertex3f(this->m_vMinPos.x, this->m_vMaxPos.y, this->m_vMaxPos.z);
		}
		glEnd();
	}
};

struct Sphere : public OBJBase
{
	vec3f m_vCenter;
	float m_fRadius;
	GLUquadricObj* m_pSphere;

	void Create(vec3f vCenter, float fRadius)
	{
		this->m_fRadius = fRadius;
		this->m_vCenter = vCenter;
		this->m_pSphere = gluNewQuadric();
	}

	void Render()
	{
		gluSphere(this->m_pSphere, this->m_fRadius, 32, 32);
	}

	void Delete()
	{
		gluDeleteQuadric(m_pSphere);
	}
};

struct Cylinder : public OBJBase
{	
	vec3f m_vBaseCenter;
	float m_fRadius;
	float m_fHeight;
	int m_nSlices;
	int m_nStacks;
	GLUquadricObj* m_pCylinder;

	void Create(vec3f vBase, float fHeight, float fRadius, int nSlice, int nStack)
	{
		this->m_vBaseCenter.make_zero();
		this->m_nSlices = nSlice;
		this->m_nStacks = nStack;
		this->m_fHeight = fHeight;
		this->m_fRadius = fRadius;
		this->m_vBaseCenter = vBase;
		this->m_pCylinder = gluNewQuadric();
		this->m_nType = MOBJ_CYLINDER;
	}

	void Render()
	{
		gluCylinder(this->m_pCylinder, this->m_fRadius, this->m_fRadius, this->m_fHeight, this->m_nSlices, this->m_nStacks);
	}
	
	void Delete()
	{
		gluDeleteQuadric(m_pCylinder);
	}
};
struct TriggerLocation : public Sphere
{
	char* m_szName;
};

struct MovingPlatform : public AABB
{
	int m_nTriggerStart;
	int m_nTriggerEnd;
	float m_fPauseTime;
};

struct Plane
{
	vec3f m_vNormal;
	float m_fdot;

	void Create(vec3f vP, vec3f vNorm)
	{
		vNorm.normalize();	//Saftey Measure
		m_vNormal = vNorm;
		m_fdot = dot_product(vNorm, vP);
	}
};

struct Ray
{
	vec3f m_vStart;
	vec3f m_vDirection;

	void Create(vec3f start, vec3f point)
	{
		m_vStart = start;
		m_vDirection = point - start;
		m_vDirection.normalize();
	}
};


#endif